package com.lib.okhttp.reqbody;

import android.os.Handler;
import android.os.Message;

import com.lib.okhttp.NetClient;

import java.io.IOException;
import java.lang.ref.WeakReference;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

public class ProgressRequestBody extends RequestBody {

    private RequestBody originalRequestBody;
    private BufferedSink bufferedSink;
    private Handler mHandler;

    public ProgressRequestBody(RequestBody originalRequestBody, Handler handler) {
        this.originalRequestBody = originalRequestBody;
        mHandler = new WeakReference<>(handler).get();
    }

    @Override
    public MediaType contentType() {
        return originalRequestBody.contentType();
    }

    @Override
    public long contentLength() throws IOException {
        return originalRequestBody.contentLength();
    }

    @Override
    public void writeTo(BufferedSink originalSink) throws IOException {

        if (bufferedSink == null) {
            Sink sink = new InnerForwardingSink(originalSink, originalRequestBody.contentLength());
            bufferedSink = Okio.buffer(sink);
        }
        originalRequestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }

    private class InnerForwardingSink extends ForwardingSink {
        private long bytesWritten;
        private long contentLength;
        private int lastPercentage;

        public InnerForwardingSink(Sink sink, long contentLength) {
            super(sink);
            this.contentLength = contentLength;
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);

            if (mHandler != null) {
                bytesWritten += byteCount;
                int percentage = (int) ((100.0 * bytesWritten) / contentLength);
                //每处理1%则立即回调
                if (percentage != lastPercentage) {
                    lastPercentage = percentage;

                    Message msg = Message.obtain();
                    msg.what = NetClient.InnerHandler.MSG_PROGRESS;
                    msg.obj = lastPercentage;
                    mHandler.sendMessage(msg);
                }
            }
        }
    }
}